﻿using System;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Ink;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;
using System.Collections.Generic;
using System.Linq;

namespace CalculationDemo
{
    public class Calculation
    {
        #region Oil Unit Network effective capacity calculation
        //note : 
        //pre calculate
        //foreach (Unit tu in UnitListForTest)
        //{
        //    tu.EffectiveCapacity = 0;
        //    tu.IsBottleNeck = false;
        //    if (tu.UnitType == FIFPConstants.UNITTYPE_TOWER)
        //            tu.Capacity = 0;
        //}     
        // Capacity  :  the unit's own capacity
        // Effective Capacity : the overall capacity of the unit and all it's child
        public  void OilUnitCalculatation(Unit node, List<Unit> unitList)
        {          
            if (isLeafNode(node, unitList))
            {
                List<Unit> wells = getChildWells(node.UnitID, unitList);
                foreach (Unit child in wells)
                {                    
                    node.EffectiveCapacity += child.Capacity;
                    node.Capacity += child.Capacity;
                    child.EffectiveCapacity = child.Capacity;                   
                }
            }
            else
            {
                if (node.UnitType == FIFPConstants.UNITTYPE_TOWER)
                {
                    List<Unit> children = getChildWithoutWells(node.UnitID, unitList);
                    foreach (Unit child in children)
                    {
                        OilUnitCalculatation(child, unitList);
                        node.EffectiveCapacity += child.EffectiveCapacity;                        
                    }

                    List<Unit> wells = getChildWells(node.UnitID, unitList);
                    foreach (Unit well in wells)
                    {
                        node.EffectiveCapacity += well.Capacity;
                        well.EffectiveCapacity = well.Capacity;
                        node.Capacity += well.Capacity;
                    }
                }
                else if (node.UnitType == FIFPConstants.UNITTYPE_RADIAL || node.UnitType == FIFPConstants.UNITTYPE_PIPELINE)
                {
                    List<Unit> children = getChilden(node.UnitID, unitList);
                    double childrenEffectiveCapacity = 0;
                    double childrenCapacity = 0;
                    foreach (Unit child in children)
                    {
                        OilUnitCalculatation(child, unitList);
                        childrenEffectiveCapacity += child.EffectiveCapacity;
                        childrenCapacity += child.Capacity;
                    }

                    node.EffectiveCapacity = Math.Min(node.Capacity, childrenEffectiveCapacity);
                    if (node.Capacity < childrenEffectiveCapacity)
                        node.IsBottleNeck = true;
                }
                //else if (node.UnitType == FIFPConstants.UNITTYPE_PIPELINE)
                //{
                //    List<Unit> children = getChilden(node.UnitID, unitList);
                //    CalculateWithRadial(children[0], unitList);
                //    node.EffectiveCapacity = Math.Min(node.Capacity, children[0].EffectiveCapacity);  
                 
                //    if(node.Capacity < children[0].EffectiveCapacity)
                //        node.IsBottleNeck = true;
                //}
            }
        }

        public void OilUnitCalculatationWithStrings(Unit node, List<Unit> unitList)
        {
            if (isLeafNode(node, unitList))
            {
                List<Unit> wells = getChildWells(node.UnitID, unitList);
                foreach (Unit child in wells)
                {
                    node.EffectiveCapacity += child.Capacity;
                    node.Capacity += child.Capacity;
                    child.EffectiveCapacity = child.Capacity;
                }
            }
            else
            {
                if (node.UnitType == FIFPConstants.UNITTYPE_TOWER)
                {
                    List<Unit> children = getChildWithoutWells(node.UnitID, unitList);
                    foreach (Unit child in children)
                    {
                        OilUnitCalculatationWithStrings(child, unitList);
                        node.EffectiveCapacity += child.EffectiveCapacity;
                    }

                    List<Unit> wells = getChildWells(node.UnitID, unitList);
                    foreach (Unit well in wells)
                    {
                        node.EffectiveCapacity += well.Capacity;
                        well.EffectiveCapacity = well.Capacity;
                        node.Capacity += well.Capacity;
                    }
                }
                else if (node.UnitType == FIFPConstants.UNITTYPE_RADIAL || node.UnitType == FIFPConstants.UNITTYPE_PIPELINE)
                {
                    List<Unit> children = getChilden(node.UnitID, unitList);
                    double childrenEffectiveCapacity = 0;
                    double childrenCapacity = 0;
                    foreach (Unit child in children)
                    {
                        OilUnitCalculatationWithStrings(child, unitList);
                        childrenEffectiveCapacity += child.EffectiveCapacity;
                        childrenCapacity += child.Capacity;
                    }

                    node.EffectiveCapacity = Math.Min(node.Capacity, childrenEffectiveCapacity);
                    if (node.Capacity < childrenEffectiveCapacity)
                        node.IsBottleNeck = true;
                }              
            }
        }

        //leaf node means this is a tower node and has only well as child
        private  bool isLeafNode(Unit node, List<Unit> unitList)
        {
            bool isLeafNode = false;

            if (node.UnitType != FIFPConstants.UNITTYPE_TOWER)
            {
                isLeafNode = false;
            }
            else
            {
                if (hasPipelineAsChild(node, unitList))
                {
                    isLeafNode = false;
                }
                else
                {
                    isLeafNode = true;
                }
            }

            return isLeafNode;
        }

        private  bool hasPipelineAsChild(Unit node, List<Unit> unitList)
        {
            bool hasPipelineAsChild = false;

            List<Unit> resultList = (from item in unitList
                                     where item.UnitType == FIFPConstants.UNITTYPE_PIPELINE && item.ParentUnitID == node.UnitID
                                     select item).ToList<Unit>();

            if (resultList.Count != 0)
                hasPipelineAsChild = true;

            return hasPipelineAsChild;
        }

        private double getWellChildStringCapacity(int wellId, List<Unit> unitList)
        {
            double childStringCapacity = 0;

            List<Unit> children = (from item in unitList
                                   where item.ParentUnitID == wellId
                                   select item).ToList<Unit>();

            return childStringCapacity;
        }
        #endregion

        //#region Water Network distribution calculation
        //public void WaterUnitEffectiveCapacityCalculation(Unit node, List<Unit> waterUnitList)
        //{
        //    OilUnitCalculatation(node, waterUnitList);
        //}

        //public void DistributeForRadialFromFacility()
        //{
        //    //get all water facility real capacity : sum(fC)

        //    //get all radial real capacity : sum(rC)

        //    //if sum(fC) < sum(rC)
        //    //Distribute sum(fC) to each Radial by their rC ratio. for example,  distribute(r1) = ( r1C / sum(rC)) * sum(fC)
        //    //else 
        //    //return
        //}

        //public void DistributetoString(Unit node, List<Unit> unitsUnderRadial)
        //{
        //    List<Unit> children = getChilden(node.UnitID, unitsUnderRadial);

        //    double sumCapacityForChildren = 0;
        //    foreach(Unit u in children)
        //    {
        //        sumCapacityForChildren += u.EffectiveCapacity;
        //    }

        //    foreach (Unit u in children)
        //    {
        //        //first distribute, from pipeline to chid
        //        u.CapacityAfterDistribution = ( u.EffectiveCapacity / sumCapacityForChildren ) * node.CapacityAfterDistribution;

        //        //assume only tower connected to radial or pipeline                
        //        if (u.UnitType == FIFPConstants.UNITTYPE_TOWER)
        //        {
        //            List<Unit> allChildrenFromU = getChilden(u.UnitID, unitsUnderRadial);
        //            List<Unit> allWellFromU     = getChildWells(u.UnitID, unitsUnderRadial);

        //            //if it is leaf tower
        //            if (allChildrenFromU.Count == allWellFromU.Count)
        //            {
        //                double tempSumValue = 0;
        //                foreach(Unit w in allWellFromU) 
        //                {
        //                    tempSumValue += w.Capacity;
        //                }

        //                foreach (Unit w in allWellFromU)
        //                {
        //                    w.CapacityAfterDistribution = (w.Capacity / tempSumValue) * u.CapacityAfterDistribution;
        //                }
        //            }
        //            //if it is not leaf tower
        //            else 
        //            {
        //                double tempSumValue = 0;
        //                foreach (Unit w in allChildrenFromU)
        //                {
        //                    if (w.UnitType == FIFPConstants.UNITTYPE_WELL)
        //                        tempSumValue += w.Capacity;
        //                    else if (w.UnitType == FIFPConstants.UNITTYPE_PIPELINE)
        //                        tempSumValue += w.EffectiveCapacity;                            
        //                }

        //                foreach (Unit c in allChildrenFromU)
        //                {
        //                    if(c.UnitType == FIFPConstants.UNITTYPE_WELL)
        //                        c.CapacityAfterDistribution = (c.Capacity / tempSumValue) * u.CapacityAfterDistribution;
        //                    else if(c.UnitType == FIFPConstants.UNITTYPE_PIPELINE)
        //                        c.CapacityAfterDistribution = (c.EffectiveCapacity / tempSumValue) * u.CapacityAfterDistribution;
        //                }

        //                foreach (Unit p in allChildrenFromU)
        //                {
        //                    if (p.UnitType == FIFPConstants.UNITTYPE_PIPELINE)
        //                    {
        //                        DistributetoString(p, unitsUnderRadial);
        //                    }
        //                }
        //            }
        //        }
        //    }            
        //}
        //#endregion

        private  Unit getParentNode(int parentUnitId, List<Unit> unitList)
        {
            List<Unit> parent = (from item in unitList
                                 where item.UnitID == parentUnitId
                                 select item).ToList<Unit>();

            if (parent.Count != 0)
                return parent[0];
            else
                return null;
        }

        private  List<Unit> getChilden(int unitID, List<Unit> unitList)
        {
            List<Unit> children = (from item in unitList
                                   where item.ParentUnitID == unitID
                                   select item).ToList<Unit>();
            return children;
        }

        private List<Unit> getChildWells(int unitID, List<Unit> unitList)
        {
            List<Unit> children = (from item in unitList
                                   where item.ParentUnitID == unitID && item.UnitType == FIFPConstants.UNITTYPE_WELL
                                   select item).ToList<Unit>();
            return children;
        }

        private List<Unit> getChildWithoutWells(int unitID, List<Unit> unitList)
        {
            List<Unit> children = (from item in unitList
                                   where item.ParentUnitID == unitID && item.UnitType != FIFPConstants.UNITTYPE_WELL
                                   select item).ToList<Unit>();
            return children;
        }

        public  List<Unit> LoadUnitsS1()
        {
            List<Unit> unitList = new List<Unit>();

            unitList.Add(new Unit() { ParentUnitID = -1, UnitID = 0, UnitName = "Tower1", UnitType = FIFPConstants.UNITTYPE_TOWER, Capacity = 100 });
            unitList.Add(new Unit() { ParentUnitID = 0, UnitID = 1, UnitName = "Pipeline1", UnitType = FIFPConstants.UNITTYPE_PIPELINE, Capacity = 300 });
            unitList.Add(new Unit() { ParentUnitID = 1, UnitID = 2, UnitName = "Tower2", UnitType = FIFPConstants.UNITTYPE_TOWER, Capacity = 100 });
            unitList.Add(new Unit() { ParentUnitID = 2, UnitID = 3, UnitName = "Pipeline2", UnitType = FIFPConstants.UNITTYPE_PIPELINE, Capacity = 50 });
            unitList.Add(new Unit() { ParentUnitID = 3, UnitID = 4, UnitName = "Tower3", UnitType = FIFPConstants.UNITTYPE_TOWER, Capacity = 100 });

            return unitList;
        }

        public  List<Unit> LoadUnitsS2()
        {
            List<Unit> unitList = new List<Unit>();

            unitList.Add(new Unit() { ParentUnitID = -1, UnitID = 0, UnitName = "Tower1", UnitType = FIFPConstants.UNITTYPE_TOWER, Capacity = 100 });
            unitList.Add(new Unit() { ParentUnitID = 0, UnitID = 1, UnitName = "Pipeline1", UnitType = FIFPConstants.UNITTYPE_PIPELINE, Capacity = 120 });
            unitList.Add(new Unit() { ParentUnitID = 1, UnitID = 3, UnitName = "Tower2", UnitType = FIFPConstants.UNITTYPE_TOWER, Capacity = 100 });
            unitList.Add(new Unit() { ParentUnitID = 3, UnitID = 4, UnitName = "Pipeline3", UnitType = FIFPConstants.UNITTYPE_PIPELINE, Capacity = 10 });
            unitList.Add(new Unit() { ParentUnitID = 4, UnitID = 5, UnitName = "Tower3", UnitType = FIFPConstants.UNITTYPE_TOWER, Capacity = 100 });

            unitList.Add(new Unit() { ParentUnitID = 0, UnitID = 2, UnitName = "Pipeline2", UnitType = FIFPConstants.UNITTYPE_PIPELINE, Capacity = 50 });
            unitList.Add(new Unit() { ParentUnitID = 2, UnitID = 6, UnitName = "Tower3", UnitType = FIFPConstants.UNITTYPE_TOWER, Capacity = 100 });

            return unitList;
        }

        public  List<Unit> LoadUnitsS3()
        {
            List<Unit> unitList = new List<Unit>();

            unitList.Add(new Unit() { ParentUnitID = -1, UnitID = 0, UnitName = "Radial1", UnitType = FIFPConstants.UNITTYPE_RADIAL, Capacity = 1000 });
            unitList.Add(new Unit() { ParentUnitID = 0, UnitID = 1, UnitName = "Pipeline1", UnitType = FIFPConstants.UNITTYPE_PIPELINE, Capacity = 120 });
            unitList.Add(new Unit() { ParentUnitID = 1, UnitID = 2, UnitName = "Tower2", UnitType = FIFPConstants.UNITTYPE_TOWER, Capacity = 100 });
            unitList.Add(new Unit() { ParentUnitID = 0, UnitID = 3, UnitName = "Pipeline2", UnitType = FIFPConstants.UNITTYPE_PIPELINE, Capacity = 10 });
            unitList.Add(new Unit() { ParentUnitID = 3, UnitID = 4, UnitName = "Tower3", UnitType = FIFPConstants.UNITTYPE_TOWER, Capacity = 100 });

            unitList.Add(new Unit() { ParentUnitID = 0, UnitID = 5, UnitName = "Tower1", UnitType = FIFPConstants.UNITTYPE_TOWER, Capacity = 100 });

            return unitList;
        }

        public  List<Unit> LoadUnitsS4()
        {
            List<Unit> unitList = new List<Unit>();

            unitList.Add(new Unit() { ParentUnitID = -1, UnitID = 0, UnitName = "Radial1", UnitType = FIFPConstants.UNITTYPE_RADIAL, Capacity = 1000 });
            
            unitList.Add(new Unit() { ParentUnitID = 0, UnitID = 1, UnitName = "Pipeline1", UnitType = FIFPConstants.UNITTYPE_PIPELINE, Capacity = 100 });
            unitList.Add(new Unit() { ParentUnitID = 1, UnitID = 2, UnitName = "Tower1", UnitType = FIFPConstants.UNITTYPE_TOWER });
            unitList.Add(new Unit() { ParentUnitID = 2, UnitID = 12, UnitName = "Well11", UnitType = FIFPConstants.UNITTYPE_WELL, Capacity = 100 });
            
            unitList.Add(new Unit() { ParentUnitID = 0, UnitID = 3, UnitName = "Pipeline2", UnitType = FIFPConstants.UNITTYPE_PIPELINE, Capacity = 100 });
            unitList.Add(new Unit() { ParentUnitID = 3, UnitID = 4, UnitName = "Tower2", UnitType = FIFPConstants.UNITTYPE_TOWER});
            unitList.Add(new Unit() { ParentUnitID = 4, UnitID = 13, UnitName = "Well21", UnitType = FIFPConstants.UNITTYPE_WELL, Capacity = 100 });
            unitList.Add(new Unit() { ParentUnitID = 4, UnitID = 14, UnitName = "Well22", UnitType = FIFPConstants.UNITTYPE_WELL, Capacity = 150 });
            

            unitList.Add(new Unit() { ParentUnitID = 0, UnitID = 5, UnitName = "Tower3", UnitType = FIFPConstants.UNITTYPE_TOWER });
            unitList.Add(new Unit() { ParentUnitID = 5, UnitID = 15, UnitName = "Well31", UnitType = FIFPConstants.UNITTYPE_WELL, Capacity = 100 });
            unitList.Add(new Unit() { ParentUnitID = 5, UnitID = 16, UnitName = "Well32", UnitType = FIFPConstants.UNITTYPE_WELL, Capacity = 150 });
            

            unitList.Add(new Unit() { ParentUnitID = 5, UnitID = 6, UnitName = "Pipeline3", UnitType = FIFPConstants.UNITTYPE_PIPELINE, Capacity = 100 });
            unitList.Add(new Unit() { ParentUnitID = 6, UnitID = 7, UnitName = "Tower4", UnitType = FIFPConstants.UNITTYPE_TOWER });
            unitList.Add(new Unit() { ParentUnitID = 7, UnitID = 17, UnitName = "Well41", UnitType = FIFPConstants.UNITTYPE_WELL, Capacity = 100 });
            unitList.Add(new Unit() { ParentUnitID = 7, UnitID = 18, UnitName = "Well42", UnitType = FIFPConstants.UNITTYPE_WELL, Capacity = 150 });
            


            unitList.Add(new Unit() { ParentUnitID = 5, UnitID = 8, UnitName = "Pipeline4", UnitType = FIFPConstants.UNITTYPE_PIPELINE, Capacity = 100 });
            unitList.Add(new Unit() { ParentUnitID = 8, UnitID = 9, UnitName = "Tower5", UnitType = FIFPConstants.UNITTYPE_TOWER });
            unitList.Add(new Unit() { ParentUnitID = 9, UnitID = 19, UnitName = "Well51", UnitType = FIFPConstants.UNITTYPE_WELL, Capacity = 200 });
           

            unitList.Add(new Unit() { ParentUnitID = 7, UnitID = 10, UnitName = "Pipeline5", UnitType = FIFPConstants.UNITTYPE_PIPELINE, Capacity = 120 });
            unitList.Add(new Unit() { ParentUnitID = 10, UnitID = 11, UnitName = "Tower6", UnitType = FIFPConstants.UNITTYPE_TOWER,  });
            unitList.Add(new Unit() { ParentUnitID = 11, UnitID = 20, UnitName = "Well61", UnitType = FIFPConstants.UNITTYPE_WELL, Capacity = 200 });
            unitList.Add(new Unit() { ParentUnitID = 11, UnitID = 21, UnitName = "Well62", UnitType = FIFPConstants.UNITTYPE_WELL, Capacity = 150 });


            unitList.Add(new Unit() { ParentUnitID = 6,  UnitID = 22, UnitName = "Pipeline6", UnitType = FIFPConstants.UNITTYPE_PIPELINE, Capacity = 100 });
            unitList.Add(new Unit() { ParentUnitID = 22, UnitID = 23, UnitName = "Tower7", UnitType = FIFPConstants.UNITTYPE_TOWER, });
            unitList.Add(new Unit() { ParentUnitID = 23, UnitID = 24, UnitName = "Well71", UnitType = FIFPConstants.UNITTYPE_WELL, Capacity = 50 });


            return unitList;
        }

        public List<Unit> LoadUnitsS4WithStrings()
        {
            List<Unit> unitList = new List<Unit>();

            unitList.Add(new Unit() { ParentUnitID = -1, UnitID = 0, UnitName = "Radial1", UnitType = FIFPConstants.UNITTYPE_RADIAL, Capacity = 1000 });

            unitList.Add(new Unit() { ParentUnitID = 0, UnitID = 1, UnitName = "Pipeline1", UnitType = FIFPConstants.UNITTYPE_PIPELINE, Capacity = 100 });
            unitList.Add(new Unit() { ParentUnitID = 1, UnitID = 2, UnitName = "Tower1", UnitType = FIFPConstants.UNITTYPE_TOWER });
            unitList.Add(new Unit() { ParentUnitID = 2, UnitID = 12, UnitName = "Well11", UnitType = FIFPConstants.UNITTYPE_WELL });
            unitList.Add(new Unit() { ParentUnitID = 12, UnitID = 41, UnitName = "String11/1", UnitType = FIFPConstants.UNITTYPE_STRING, Capacity = 100 });


            unitList.Add(new Unit() { ParentUnitID = 0, UnitID = 3, UnitName = "Pipeline2", UnitType = FIFPConstants.UNITTYPE_PIPELINE, Capacity = 100 });
            unitList.Add(new Unit() { ParentUnitID = 3, UnitID = 4, UnitName = "Tower2", UnitType = FIFPConstants.UNITTYPE_TOWER });
            unitList.Add(new Unit() { ParentUnitID = 4, UnitID = 13, UnitName = "Well21", UnitType = FIFPConstants.UNITTYPE_WELL });
            unitList.Add(new Unit() { ParentUnitID = 4, UnitID = 14, UnitName = "Well22", UnitType = FIFPConstants.UNITTYPE_WELL});
            unitList.Add(new Unit() { ParentUnitID = 13, UnitID = 42, UnitName = "String21/1", UnitType = FIFPConstants.UNITTYPE_STRING, Capacity = 100 });
            unitList.Add(new Unit() { ParentUnitID = 14, UnitID = 43, UnitName = "String22/1", UnitType = FIFPConstants.UNITTYPE_STRING, Capacity = 150 });


            unitList.Add(new Unit() { ParentUnitID = 0, UnitID = 5, UnitName = "Tower3", UnitType = FIFPConstants.UNITTYPE_TOWER });
            unitList.Add(new Unit() { ParentUnitID = 5, UnitID = 15, UnitName = "Well31", UnitType = FIFPConstants.UNITTYPE_WELL });
            unitList.Add(new Unit() { ParentUnitID = 5, UnitID = 16, UnitName = "Well32", UnitType = FIFPConstants.UNITTYPE_WELL });
            unitList.Add(new Unit() { ParentUnitID = 15, UnitID = 44, UnitName = "String31/1", UnitType = FIFPConstants.UNITTYPE_STRING, Capacity = 100 });
            unitList.Add(new Unit() { ParentUnitID = 16, UnitID = 45, UnitName = "String32/1", UnitType = FIFPConstants.UNITTYPE_STRING, Capacity = 150 });


            unitList.Add(new Unit() { ParentUnitID = 5, UnitID = 6, UnitName = "Pipeline3", UnitType = FIFPConstants.UNITTYPE_PIPELINE, Capacity = 100 });
            unitList.Add(new Unit() { ParentUnitID = 6, UnitID = 7, UnitName = "Tower4", UnitType = FIFPConstants.UNITTYPE_TOWER });
            unitList.Add(new Unit() { ParentUnitID = 7, UnitID = 17, UnitName = "Well41", UnitType = FIFPConstants.UNITTYPE_WELL });
            unitList.Add(new Unit() { ParentUnitID = 7, UnitID = 18, UnitName = "Well42", UnitType = FIFPConstants.UNITTYPE_WELL });
            unitList.Add(new Unit() { ParentUnitID = 17, UnitID = 46, UnitName = "String41/1", UnitType = FIFPConstants.UNITTYPE_STRING, Capacity = 100 });
            unitList.Add(new Unit() { ParentUnitID = 18, UnitID = 47, UnitName = "String42/1", UnitType = FIFPConstants.UNITTYPE_STRING, Capacity = 150 });



            unitList.Add(new Unit() { ParentUnitID = 5, UnitID = 8, UnitName = "Pipeline4", UnitType = FIFPConstants.UNITTYPE_PIPELINE, Capacity = 200 });
            unitList.Add(new Unit() { ParentUnitID = 8, UnitID = 9, UnitName = "Tower5", UnitType = FIFPConstants.UNITTYPE_TOWER });
            unitList.Add(new Unit() { ParentUnitID = 9, UnitID = 19, UnitName = "Well51", UnitType = FIFPConstants.UNITTYPE_WELL });
            unitList.Add(new Unit() { ParentUnitID = 17, UnitID = 48, UnitName = "String51/1", UnitType = FIFPConstants.UNITTYPE_STRING, Capacity = 200 });



            unitList.Add(new Unit() { ParentUnitID = 7, UnitID = 10, UnitName = "Pipeline5", UnitType = FIFPConstants.UNITTYPE_PIPELINE, Capacity = 120 });
            unitList.Add(new Unit() { ParentUnitID = 10, UnitID = 11, UnitName = "Tower6", UnitType = FIFPConstants.UNITTYPE_TOWER, });
            unitList.Add(new Unit() { ParentUnitID = 11, UnitID = 20, UnitName = "Well61", UnitType = FIFPConstants.UNITTYPE_WELL });
            unitList.Add(new Unit() { ParentUnitID = 11, UnitID = 21, UnitName = "Well62", UnitType = FIFPConstants.UNITTYPE_WELL });
            unitList.Add(new Unit() { ParentUnitID = 20, UnitID = 49, UnitName = "String61/1", UnitType = FIFPConstants.UNITTYPE_STRING, Capacity = 200 });
            unitList.Add(new Unit() { ParentUnitID = 21, UnitID = 50, UnitName = "String62/1", UnitType = FIFPConstants.UNITTYPE_STRING, Capacity = 150 });


            unitList.Add(new Unit() { ParentUnitID = 6, UnitID = 22, UnitName = "Pipeline6", UnitType = FIFPConstants.UNITTYPE_PIPELINE, Capacity = 100 });
            unitList.Add(new Unit() { ParentUnitID = 22, UnitID = 23, UnitName = "Tower7", UnitType = FIFPConstants.UNITTYPE_TOWER, });
            unitList.Add(new Unit() { ParentUnitID = 23, UnitID = 24, UnitName = "Well71", UnitType = FIFPConstants.UNITTYPE_WELL });
            unitList.Add(new Unit() { ParentUnitID = 24, UnitID = 51, UnitName = "String71/1", UnitType = FIFPConstants.UNITTYPE_STRING, Capacity = 25 });
            unitList.Add(new Unit() { ParentUnitID = 24, UnitID = 52, UnitName = "String71/2", UnitType = FIFPConstants.UNITTYPE_STRING, Capacity = 25 });


            return unitList;
        }

        public List<Unit> LoadWaterUnitsS1()
        {
            List<Unit> unitList = new List<Unit>();

            unitList.Add(new Unit() { ParentUnitID = -1, UnitID = 0, UnitName = "Radial1", UnitType = FIFPConstants.UNITTYPE_RADIAL, Capacity = 1000 });

            unitList.Add(new Unit() { ParentUnitID = 0, UnitID = 1, UnitName = "Tower1", UnitType = FIFPConstants.UNITTYPE_TOWER });
            unitList.Add(new Unit() { ParentUnitID = 1, UnitID = 2, UnitName = "Well11", UnitType = FIFPConstants.UNITTYPE_WELL, Capacity = 100 });

            unitList.Add(new Unit() { ParentUnitID = 1, UnitID = 3, UnitName = "Pipeline1", UnitType = FIFPConstants.UNITTYPE_PIPELINE, Capacity = 300 });
            unitList.Add(new Unit() { ParentUnitID = 3, UnitID = 4, UnitName = "Tower2", UnitType = FIFPConstants.UNITTYPE_TOWER });
            unitList.Add(new Unit() { ParentUnitID = 4, UnitID = 5, UnitName = "Well21", UnitType = FIFPConstants.UNITTYPE_WELL, Capacity = 100 });
            unitList.Add(new Unit() { ParentUnitID = 4, UnitID = 13, UnitName = "Well22", UnitType = FIFPConstants.UNITTYPE_WELL, Capacity = 100 });

            unitList.Add(new Unit() { ParentUnitID = 4, UnitID = 6, UnitName = "Pipeline2", UnitType = FIFPConstants.UNITTYPE_PIPELINE, Capacity = 200 });
            unitList.Add(new Unit() { ParentUnitID = 6, UnitID = 7, UnitName = "Tower3", UnitType = FIFPConstants.UNITTYPE_TOWER });
            unitList.Add(new Unit() { ParentUnitID = 7, UnitID = 8, UnitName = "Well31", UnitType = FIFPConstants.UNITTYPE_WELL, Capacity = 100 });

            unitList.Add(new Unit() { ParentUnitID = 1, UnitID = 9, UnitName = "Pipeline3", UnitType = FIFPConstants.UNITTYPE_PIPELINE, Capacity = 200 });
            unitList.Add(new Unit() { ParentUnitID = 9, UnitID = 10, UnitName = "Tower4", UnitType = FIFPConstants.UNITTYPE_TOWER });
            unitList.Add(new Unit() { ParentUnitID = 10, UnitID = 11, UnitName = "Well41", UnitType = FIFPConstants.UNITTYPE_WELL, Capacity = 100 });
            unitList.Add(new Unit() { ParentUnitID = 10, UnitID = 12, UnitName = "Well42", UnitType = FIFPConstants.UNITTYPE_WELL, Capacity = 100 });

            return unitList;
        }



        //private List<Unit> GeUnitNameList(List<Unit> lstUnits)
        //{
        //    return (from unit in lstUnits
        //            select new Unit()
        //            {                      
        //                UnitNameList = this.GeUnitNameList(UnitList.Where(p => p.ParentUnitID == unit.UnitID).ToList())
        //            }).ToList();
        //}

        public void Calculate(Unit node, List<Unit> unitList)
        {
            if (isLeafNode(node, unitList))
            {
                node.EffectiveCapacity = node.Capacity;
            }
            else
            {
                if (node.UnitType == FIFPConstants.UNITTYPE_TOWER)
                {
                    List<Unit> children = getChilden(node.UnitID, unitList);
                    node.EffectiveCapacity = node.Capacity;
                    foreach (Unit child in children)
                    {
                        Calculate(child, unitList);
                        node.EffectiveCapacity += child.EffectiveCapacity;
                    }
                }
                else if (node.UnitType == FIFPConstants.UNITTYPE_PIPELINE)
                {
                    List<Unit> children = getChilden(node.UnitID, unitList);
                    Calculate(children[0], unitList);
                    node.EffectiveCapacity = Math.Min(node.Capacity, children[0].EffectiveCapacity);
                }
            }
        }
    }
}
